<?php

namespace App\Repository;

use App\Common\Libs\ArrayHelper;
use App\Consts\GlobalArticleConst;
use App\Consts\GlobalConst;
use App\Models\Cache\CacheKey;
use App\Models\Field\ArticleField;
use App\Models\IndexArticle;
use App\Models\Select\ArticleSelect;
use App\Models\SysArticle;
use App\Models\SysArticleContent;
use App\Models\SysArticleOriginalUrl;
use App\Models\SysArticleUser;
use Illuminate\Database\Eloquent\Builder;

/**
 * @package App\Repository
 * @see ArticleRepository
 */
class ArticleRepository extends BaseRepository
{
    /**
     * 获取用户原创文章列表
     * @param $searchParams
     * @return Builder
     */
    public function userArticleList($searchParams)
    {
        $provider = IndexArticle::getInstance()
            ->where('author_id', $searchParams['author_id'])
            ->where('type', GlobalArticleConst::ARTICLE_TYPE_ORIGINAL)
            ->where('is_deleted', GlobalConst::IS_NOT_DELETE);

        $provider->orderBy('created_at', GlobalConst::ORDER_TYPE_DESC);

        $provider->select(['article_id']);

        return $this->setPagination($provider);
    }

    public function getUserOriginalArticleList($searchParams)
    {
        $provider = IndexArticle::getInstance()
            ->where('author_id', $searchParams['author_id'])
            ->where('is_deleted', GlobalConst::IS_NOT_DELETE)
            ->whereNotIn('article_id', (array)$searchParams['ignore']);

        $provider->select(['article_id']);

        return $this->setPagination($provider, ['page_size' => $searchParams['page_size']]);
    }

    /**
     * 获取相似文章列表
     * @param $searchParams
     * @return Builder
     */
    public function getSimilarArticleList($searchParams)
    {
        $provider = IndexArticle::getInstance()
            ->where('is_deleted', GlobalConst::IS_NOT_DELETE)
            ->where('article_id', '<>', $searchParams['ignore']);

        $provider->orderByDesc('created_at'
        );

        $provider->select(['article_id']);

        return $this->setPagination($provider, ['page_size' => $searchParams['page_size']]);
    }

    /**
     * get article id list by search condition
     * @param $params
     * @return \Illuminate\Support\Collection
     */
    public function getArticleIdListBySearch($params)
    {
        $model = new SysArticle();
        $idAry = collect([]);
        for ($i = 0; $i < GlobalConst::DATABASE_TABLE_NUM; $i++) {
            $aids = $model::setTableName($model->getTable() . $i)
                ->select(['article_id'])
                ->where(function (Builder $query) use ($params) {
                    if (!empty($params['keywords_article'])) {
                        $query->where('title', 'like', "%" . $params['keywords_article'] . "%");
                    }
                    if (!empty($params['last_id'])) {
                        $query->where('article_id', '<', $params['last_id']);
                    }
                })
                ->where('is_deleted', 0)
                ->orderBy('created_at', 'desc')
                ->pluck('article_id');
            if (!empty($aids)) {
                $idAry = $idAry->merge($aids)->unique();
            }
        }
        return $idAry->unique();
    }


    /**
     * get article list by table ids
     * @param $tabAry
     * @return mixed|Builder
     */
    public function getArticleListByTabIds($tabAry)
    {
        $model = new SysArticle();

        // get articles
        $articleAry = collect([]);
        foreach ($tabAry as $table => $ids) {
            $articles = $model::setTableName($table)
                ->select($model->fields['search'])
                ->whereIn('article_id', $ids)
                ->get();
            if (!empty($articles)) {
                $articleAry = $articleAry->merge($articles->collect());
            }
        }

        return $articleAry;
    }

    /**
     * get article extra info
     * @param array $articleAry
     * @return array|\Illuminate\Support\Collection
     */
    public function getArticleExtInfo(array $articleAry)
    {
        $articleAry = collect($articleAry);
        // return result
        $result = [];
        foreach ($articleAry as $article) {
            $result[] = ArrayHelper::merge($article, [
                'count' => service()->CounterService->getTargetCount(CacheKey::COUNTER_ARTICLE, ['collect', 'note'], ['article_id' => $article['id']]),
            ]);
        }
        return $result;
    }

    /**
     * 通过分表数，获取文章基础信息
     * @param int $tableIndex
     * @param string|array $articleId
     * @param string $selectScene
     * @return SysArticle[]|Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model[]
     */
    public function getArticleByTableCount($tableIndex, $articleId, $selectScene = ArticleSelect::SELF_LIST)
    {
        $tableName = SysArticle::getTableNameByTableIndex($tableIndex);

        return SysArticle::setTableName($tableName)
            ->select(ArticleSelect::getSelects($selectScene))
            ->whereIn('article_id', (array)$articleId)
            ->get();
    }

    /**
     * 通过文章ID获取文章
     * @param $articleId
     * @param string $selectScene
     * @return Builder|SysArticle|object|null
     */
    public function getArticleByArticleId($articleId, $selectScene = ArticleField::SELF_DETAIL)
    {
        return SysArticle::getInstance($articleId)
            ->select(ArticleSelect::getSelects($selectScene))
            ->where('article_id', $articleId)
            ->first();
    }

    /**
     * 根据文章ID找到文章内容
     * @param $articleId
     * @return Builder|SysArticleContent|object|null
     */
    public function getArticleContentByArticleId($articleId)
    {
        return SysArticleContent::getInstance($articleId)
            ->where('article_id', $articleId)
            ->first();
    }

    /**
     * @param $loadData
     * @return SysArticle|Builder|\Illuminate\Database\Eloquent\Model|bool
     */
    public function create($loadData)
    {
        $article = SysArticle::getModel($loadData['article_id']);
        return $article->create($loadData) ?: false;
    }

    /**
     * @param $loadData
     * @return IndexArticle|bool|Builder|\Illuminate\Database\Eloquent\Model|object|null
     */
    public function createIndex($loadData)
    {
        $indexArticle = IndexArticle::getModel()
            ->where('article_id', $loadData['article_id'])
            ->first();
        if ($indexArticle) {
            return $indexArticle;
        }

        $indexArticle = IndexArticle::getModel();

        return $indexArticle->create($loadData) ?: false;
    }

    /**
     * @param SysArticle $article
     * @param $loadData
     * @return bool|SysArticle
     */
    public function updateArticle(SysArticle $article, $loadData)
    {
        return $article->updateFormat($loadData) ?: false;
    }

    /**
     * @param IndexArticle $articleIndex
     * @param $loadData
     * @return bool|IndexArticle
     */
    public function updateArticleIndex(IndexArticle $articleIndex, $loadData)
    {
        return $articleIndex->updateFormat($loadData) ?: false;
    }

    /**
     * @param $loadData
     * @return bool
     */
    public function createContent($loadData)
    {
        $query = SysArticleContent::getModel($loadData['article_id']);
        $articleContent = $query
            ->where('article_id', $loadData['article_id'])
            ->first();
        if ($articleContent) {
            return $articleContent;
        }

        return $query->create($loadData) ?: false;
    }

    /**
     * @param $loadData
     * @return bool
     */
    public function createOriginalUrl($loadData)
    {
        $model = SysArticleOriginalUrl::getModel(md5($loadData['original_url']));
        $articleOriginal = $model
            ->where('original_url', $loadData['original_url'])
            ->first();
        if (!$articleOriginal) {
            $articleOriginal = $model;
        }

        return $articleOriginal->create($loadData) ?: false;
    }

    /**
     * @param $loadData
     * @return bool
     */
    public function createArticleUser($loadData)
    {
        $model = SysArticleUser::getModel($loadData['article_id']);
        $articleUser = $model
            ->where('article_id', $loadData['article_id'])
            ->where('user_id', $loadData['user_id'])
            ->first();
        if (!$articleUser) {
            $articleUser = $model;
        }

        return $articleUser->create($loadData) ?: false;
    }

}
